# This is a columns transformations DSL.
class ColumnTransform < Transform

  # This method is the query builder for the column transforms. 
  # Based on the arguments hash passed, it will extract the rename,resize and datatype options.
	def self.query_builder(arg1)
      query_string = "ALTER TABLE "+arg1[:table_name]+" CHANGE "+arg1[:col_name]+" "
      if arg1[:rename_to].nil? or arg1[:rename_to].empty?
          col_name = arg1[:col_name]
      else
          col_name = arg1[:rename_to]
      end
      query_string << col_name+" "
      col_specs = get_the_col_spec_for_single_col(arg1[:col_name],arg1[:table_name],arg1[:connection])
      if !arg1[:datatype].nil?
          datatype = arg1[:datatype]
      else	
          datatype = col_specs.split("(")[0]	
      end
      query_string << datatype+"("
      if arg1[:resize_to] != nil
          new_size = arg1[:resize_to].to_s+")"
      else	
          new_size = col_specs.split("(")[1]
      end
      query_string << new_size
      puts query_string
	end	

  
  # This is for executing column transforms on tables of diff databases.
	def self.many_transforms(options={})
      options.each{|key,value|
          connection = key
          all_tables = connection.tables
          value.each{|inner_key,inner_value|
              required_tables = get_required_columns(all_tables,inner_key,"",connection)
              for single_table in required_tables
                  all_columns = get_column_list(connection,single_table)
                  required_columns = get_required_columns(all_columns,inner_value[:column_names],"",connection)
                  required_columns.each{|single_column|
                      arg_hash={:resize_to => inner_value[:resize_to],
                                      :rename_to => inner_value [:rename_as],
                                      :datatype => inner_value[:datatype],
                                      :table_name=>single_table,
                                      :col_name=>single_column,
                                      :connection=>connection}
                      ColumnTransform.query_builder(arg_hash)            
                  }
              end
          }
      }
  end  
  
  
  
  # This method will return names of tables which contain column_name. These tables will be under the database connected with connection.
	def self.column_exists?(column_name,connection)
      all_tables = connection.query("show tables")
      tables_with_column =[]
      for table_name in all_tables
          if is_column_present(column_name,table_name,connection)
              tables_with_column << table_name
          end
      end
      return tables_with_column	
	end


  
  # This method will actually parse the transformation strings for size,datatype and name. Based on these values it will execute the transform.  
	def self.method_missing(method_name,arg1)
      transform_options = method_name.to_s.split("_")
      under_index = transform_options.index("under")
      datatype_index = transform_options.index("datatype")
      resize_index = transform_options.index("resize")
      rename_index = transform_options.index("rename")
      original_column_name = (transform_options[0..under_index]-transform_options[under_index].to_a).join("_")
      tab_name_end = []
      if rename_index != nil 
          tab_name_end << rename_index 
      end	
      if resize_index != nil 
          tab_name_end << resize_index 
      end	
      if datatype_index != nil
          tab_name_end << datatype_index 
      end	
      original_table_name = transform_options[under_index+1..(tab_name_end.sort[0]-1)].join("_")
      if rename_index != nil
          tab_name_end = tab_name_end.sort
          if tab_name_end.last != rename_index
              new_col_name = tab_name_end[(tab_name_end.index(rename_index)+1).to_i]
          else
              new_col_name = transform_options.length	
          end	
          new_col_name = transform_options[rename_index+2..new_col_name-1].join("_")
      end	
      new_datatype = transform_options[datatype_index+2] if datatype_index != nil
      new_size = transform_options[resize_index+2] if resize_index != nil
      query_string = "ALTER TABLE "+original_table_name+" CHANGE "+original_column_name
      col_specs = get_the_col_spec_for_single_col(original_column_name,original_table_name,arg1)
      p ["column specs are",col_specs]
      if new_col_name != nil
          query_string << " "+new_col_name
      else
          query_string << " "+original_column_name
      end	
      if new_datatype != nil
          query_string << " "+new_datatype
      else
          if !col_specs.split("(")[0].nil?
              query_string << " "+col_specs.split("(")[0]	
          else
              query_string << " "  
          end    
      end		
      if new_size != nil
          query_string << "("+new_size+")"
      else
          if !col_specs.split("(")[1].nil?
              query_string << "("+col_specs.split("(")[1] 
          else
              query_string << " "
          end    
      end			
      puts query_string
  end	

end	